import datetime
import pandas as pd
import time
from math import floor
import tushare as ts
import threading
import os

from client import client

home_path = os.getenv('STOCK_PATH')
if home_path == '':
    home_path = '.'
data_path = home_path + '/' + 'data/'

json_path = data_path + 'stock_list.json'

locker = threading.Lock()
old_security_map = {}
security_map = {}
security_list = []

jysMap = {
    'sz': 0,
    'SZ': 0,
    'sh': 1,
    'SH': 1
}
limit = 100
pro = ts.pro_api('018098e3561e0e2f721c27a2d91da5171e8764bf73ce3bfc935b5201')


def get_stock_list():
    global security_list
    df = pro.stock_basic(exchange='', list_status='L', fields='ts_code,symbol,name,area,industry,market,exchange,list_status,list_date,delist_date')
    with open(json_path, mode='w', encoding='utf-8') as f:
        f.write(df.to_json())
    df_to_list(df)
    return security_list


def load_stock_list():
    df = pd.read_json(json_path, encoding='utf-8')
    df_to_list(df)


def df_to_list(df):
    global security_list
    for index, row in df.iterrows():
        ts_code = str(row['ts_code'])
        sp = ts_code.split('.')
        if sp[1] in jysMap:
            security_list.append((int(jysMap[sp[1]]), sp[0]))


def init_security_from_json():
    locker.acquire()
    load_stock_list()
    locker.release()


def watch_security(index):
    l = len(security_list)
    if index * limit > l:
        return
    left = index * limit
    right = (index + 1) * limit
    if right > l:
        right = l
    temp_list = security_list[left:right]
    watch_security_list(temp_list)


def watch_security_list(list):
    api = client.get_api()
    data = api.get_security_quotes(list)
    if data:
        for d in data:
            key = get_key(d)
            security_map[key] = d
    else:
        print('[error] len %d list %s ' % (len(list), list))
    client.release(api)


def get_key(dic):
    return '{}-{}'.format(dic['market'], dic['code'])


def print_security():
    while True:
        for key in old_security_map.keys():
            if old_security_map[key]:
                print(old_security_map[key]['price'], old_security_map[key]['servertime'], security_map[key]['price'],
                      security_map[key]['servertime'], )
        time.sleep(3)


def auto_list():
    get_stock_list()
    indexs = []
    n = int(len(security_list) / limit) + 1
    for i in range(n):
        indexs.append(i)
    start_time = datetime.time(hour=18)
    end_time = datetime.time(hour=19)
    running = False
    while True:
        current_time = datetime.datetime.now().time()
        if start_time <= current_time <= end_time:
            running = True
        else:
            running = False
        if running:
            start = time.time()
            threads = []
            for i in indexs:
                t = threading.Thread(target=watch_security, args=(i,))
                threads.append(t)
                t.start()
            for t in threads:
                t.join()
            end = time.time()
            print('拉取所有耗时: %0.3f s' % (end - start))
            print(len(security_map))
        time.sleep(1)


def auto_list_mult():
    start = time.time()
    l = len(security_list)
    n = floor(l/80)
    index = 0
    threads = []
    data_list = []
    for i in range(n):
        index = i * 80
        data_list.append(security_list[index:index + 80])
    data_list.append(security_list[index + 80:])

    for data in data_list:
        t = threading.Thread(target=watch_security_list, args=(data,))
        t.start()
        threads.append(t)

    for t in threads:
        t.join()
    end = time.time()
    print(l)
    print(len(security_map))
    print('拉取所有耗时: %0.3f s' % (end - start))


def auto_list_single():
    start = time.time()
    l = len(security_list)
    n = floor(l/80)
    index = 0
    data_list = []
    for i in range(n):
        index = i * 80
        data_list.append(security_list[index:index + 80])
    data_list.append(security_list[index + 80:])
    for data in data_list:
        watch_security_list(data)
    end = time.time()
    print(l)
    print(len(security_map))
    print('拉取所有耗时: %0.3f s' % (end - start))


if __name__ == '__main__':
    load_stock_list()
    # auto_list()
    auto_list_mult()
    # auto_list_single()
    client.close()

